﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using BrickBreaker;
using BrickBreaker.Core;

namespace Hud
{
    public class BBHud
    {
        // temporary until HUD can use the Global graphics object in Brick Breaker
        //GraphicsDeviceManager graphics;

        #region HUD Data Members
        //
            private int score;
            private int lives;
            private int ammo;
            private int brickCount;

            private float time;
            private float elapsedTime;

            private bool timeReached;
            
            //private SpriteFont font;

            private BBText scoreText;
            private BBText livesText;
            private BBText ammoText;
            private BBText brickCountText;
            private BBText timeText;
        //
        #endregion


        #region Accessors

        public int Score
        {
            get { return this.score; }
            set { this.score = value; }
        }

        public int Lives
        {
            get { return this.lives; }
            set { this.lives = value; }
        }

        public bool HasLives
        {
            get { return (this.lives > 0); }
        }

        public int Ammo
        {
            get { return this.ammo; }
            set { this.ammo = value; }
        }

        public bool AmmoActive
        {
            get { return ammoText.Active; }
            set { this.ammoText.Active = value; }
        }

        public int BrickCount
        {
            get { return this.brickCount; }
            set { this.brickCount = value; }
        }
        public float TimeLeft
        {
            get { return this.time; }
            set { this.time = value; }
        }

        public bool TimerActive
        {
            get { return timeText.Active; }
            set { this.timeText.Active = value; }
        }

        public bool TimeReached
        {
            get { return this.timeReached; }
            set { this.timeReached = value; }
        }

        #endregion


        #region Private Methods
        //
            /// <summary>
            /// Sets position relative to the bottom left corner of the screen.
            /// </summary>
            /// <param name="Xpercent">The percentage away from the left side of the screen. 0 (left) - 1 (right)</param>
            /// <param name="Ypercent">The percentage away from the bottom of the screen. 0 (bottom) - 1 (top)</param>
            private Vector2 PositionFromBottomLeft(float Xpercent, float Ypercent)
            {
                if (Xpercent < 0.0f)
                {
                    Xpercent = 0.0f;
                }
                else if (Xpercent > 1.0f)
                {
                    Xpercent = 1.0f;
                }

                if (Ypercent < 0.0f)
                {
                    Ypercent = 0.0f;
                }
                else if (Ypercent > 1.0f)
                {
                    Ypercent = 1.0f;
                }

                Vector2 pos = Vector2.Zero;
                Vector2 screen = new Vector2(BBGlobalConfig.graphics.PreferredBackBufferWidth, BBGlobalConfig.graphics.PreferredBackBufferHeight);
     
                pos.Y = screen.Y;

                pos += new Vector2(screen.X * Xpercent, -(screen.Y * Ypercent));

                return pos;
            }

            /// <summary>
            /// Sets position relative to the bottom right corner of the screen.
            /// </summary>
            /// <param name="Xpercent">The percentage away from the right side of the screen. 0 (right) - 1 (left)</param>
            /// <param name="Ypercent">The percentage away from the bottom of the screen. 0 (bottom) - 1 (top)</param>
            private Vector2 PositionFromBottomRight(float Xpercent, float Ypercent)
            {
                if (Xpercent < 0.0f)
                {
                    Xpercent = 0.0f;
                }
                else if (Xpercent > 1.0f)
                {
                    Xpercent = 1.0f;
                }

                if (Ypercent < 0.0f)
                {
                    Ypercent = 0.0f;
                }
                else if (Ypercent > 1.0f)
                {
                    Ypercent = 1.0f;
                }

                Vector2 screen = new Vector2(BBGlobalConfig.graphics.PreferredBackBufferWidth, BBGlobalConfig.graphics.PreferredBackBufferHeight);

                Vector2 pos = screen;

                pos -= new Vector2(screen.X * Xpercent, screen.Y * Ypercent);

                return pos;
            }

            /// <summary>
            /// Sets position relative to the top left corner of the screen.
            /// </summary>
            /// <param name="Xpercent">The percentage away from the left side of the screen. 0 (left) - 1 (right)</param>
            /// <param name="Ypercent">The percentage away from the bottom of the screen. 0 (top) - 1 (bottom)</param>
            private Vector2 PositionFromTopLeft(float Xpercent, float Ypercent)
            {
                if (Xpercent < 0.0f)
                {
                    Xpercent = 0.0f;
                }
                else if (Xpercent > 1.0f)
                {
                    Xpercent = 1.0f;
                }

                if (Ypercent < 0.0f)
                {
                    Ypercent = 0.0f;
                }
                else if (Ypercent > 1.0f)
                {
                    Ypercent = 1.0f;
                }

                Vector2 pos = Vector2.Zero;
                Vector2 screen = new Vector2(BBGlobalConfig.graphics.PreferredBackBufferWidth, BBGlobalConfig.graphics.PreferredBackBufferHeight);

                pos += new Vector2(screen.X * Xpercent, screen.Y * Ypercent);

                return pos;
            }

            /// <summary>
            /// Sets position relative to the top right corner of the screen.
            /// </summary>
            /// <param name="Xpercent">The percentage away from the right side of the screen. 0 (right) - 1 (left)</param>
            /// <param name="Ypercent">The percentage away from the top of the screen. 0 (top) - 1 (bottom)</param>
            private Vector2 PositionFromTopRight(float Xpercent, float Ypercent)
            {
                if (Xpercent < 0.0f)
                {
                    Xpercent = 0.0f;
                }
                else if (Xpercent > 1.0f)
                {
                    Xpercent = 1.0f;
                }

                if (Ypercent < 0.0f)
                {
                    Ypercent = 0.0f;
                }
                else if (Ypercent > 1.0f)
                {
                    Ypercent = 1.0f;
                }

                Vector2 pos = Vector2.Zero;
                Vector2 screen = new Vector2(BBGlobalConfig.graphics.PreferredBackBufferWidth, BBGlobalConfig.graphics.PreferredBackBufferHeight);

                pos.X = screen.X;

                pos -= new Vector2(screen.X * Xpercent, -(screen.Y * Ypercent));

                return pos;
            }
        //
        #endregion


        #region Object Construction
        //
            /// <summary>
            /// Creates the HUD object for the game. Score is initially set to Zero
            /// </summary>
            /// <param name="lives">The number of lives the player starts with.</param>
            /// <param name="numOfBricks">The number of bricks in the level.</param>
            public BBHud(int lives, int numOfBricks)
            {
                this.score = 0;
                this.lives = lives;
                this.ammo = 0;
                this.brickCount = numOfBricks;

                this.time = 0.0f;
                this.timeReached = false;

                // Bottom of screen
                this.scoreText = new BBText("Score: " + this.score.ToString(), PositionFromBottomLeft(0.01f, 0.04f), Color.White, true);
                this.livesText = new BBText("Lives: " + this.lives.ToString(), PositionFromBottomRight(0.1f, 0.04f), Color.White, true);
                this.ammoText = new BBText("Ammo: " + this.ammo.ToString(), PositionFromTopLeft(0.0f, 0.0f), Color.White, false);
                this.brickCountText = new BBText("Bricks Left: " + this.brickCount.ToString(), PositionFromBottomLeft(0.42f, 0.04f), Color.White, true);

                // Top of screen
                this.timeText = new BBText("Time Left: " + this.time.ToString(), PositionFromTopLeft(0.45f, 0.0f), Color.White, false);
            }
        //
        #endregion


        #region Public Methods
        //
            /// <summary>
            /// Updates the HUD object for the game.
            /// </summary>
            public void Update(GameTime gameTime)
            {
                if (score < 0)
                {
                    this.score = 0;
                }

                if (lives < 0)
                {
                    this.lives = 0;
                }

                if (brickCount < 0)
                {
                    this.brickCount = 0;
                }

                if (ammo <= 0)
                {
                    this.ammo = 0;
                    this.brickCountText.Position = PositionFromBottomLeft(0.42f, 0.04f);
                }
                else
                {
                    this.brickCountText.Position = PositionFromBottomLeft(0.35f, 0.04f);
                    this.ammoText.Position = PositionFromBottomLeft(0.55f, 0.04f);
                }

                if (time < 0.0f)
                {
                    this.time = 0.0f;
                }

                if (this.timeText.Active)
                {
                    if (this.time >= this.elapsedTime)
                    {
                        this.time = 0.0f;
                        this.timeText.Active = false;
                        this.timeReached = true;
                    }
                    else
                    {
                        this.time += (float)gameTime.ElapsedGameTime.TotalSeconds;
                    }
                }

                this.scoreText.Text = "Score: " + this.score.ToString();
                this.livesText.Text = "Lives: " + this.lives.ToString();
                this.ammoText.Text = "Ammo: " + this.ammo.ToString();
                this.brickCountText.Text = "Bricks Left: " + this.brickCount.ToString();
                
                this.timeText.Text = "Time Left: " + Math.Round(this.elapsedTime - this.time, 0).ToString();
            }

            /// <summary>
            /// Draws the HUD object for the game.
            /// </summary>
            /// <param name="spriteBatch">Your spritebatch.  Make sure you have already called begin().</param>
            public void Draw(SpriteBatch spriteBatch)
            {
                this.scoreText.Draw(spriteBatch);
                this.livesText.Draw(spriteBatch);
                this.ammoText.Draw(spriteBatch);
                this.brickCountText.Draw(spriteBatch);
                this.timeText.Draw(spriteBatch);
            }

            //public void SetAmmoPosition(BBSingleSprite sprite)
            //{
            //    this.ammoText.Position = (sprite.Position + (sprite.Size / 2)) - (this.ammoText.Size / 2);
            //}

            public void StartTimer(float amountOfTime)
            {
                this.elapsedTime = amountOfTime;
                this.timeText.Active = true;
            }

            //public void StopTimer()
            //{
            //    if (this.time >= amountOfTime)
            //    {
            //        this.timeText.Active = false;
            //        this.time = 0.0f;
            //    }
            //}

        //
        #endregion

    }
}
